#ifndef __LOG_H__
#define __LOG_H__

#include <boost/function.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/thread/mutex.hpp>
#include <list>
#include <vector>
#include <string>
#include <sstream>

class Log {
public:
	virtual ~Log() {
		std::vector<fun_call> tmpFun;
		{
			boost::mutex::scoped_lock lock(m_Mutex);
			tmpFun.swap(m_Fun);
		}
		tmpFun.clear();
	};

	typedef boost::function<void(const std::string&, const std::string&)> fun_call;
	virtual bool addLog(fun_call fun) {
		boost::mutex::scoped_lock lock(m_Mutex);
		m_Fun.push_back(fun);
		return true;
	};
	virtual void notify(const std::string& tag, const std::string& msg) {
		std::vector<fun_call> tmpFun;
		{
			boost::mutex::scoped_lock lock(m_Mutex);
			tmpFun = m_Fun;
		}
		for (auto Iter = tmpFun.begin(); Iter != tmpFun.end(); ++Iter)
		{
			(*Iter)(tag, msg);
		}
	};

	static boost::shared_ptr<Log> getInstance() {
		static boost::shared_ptr<Log> gInstance;
		static boost::mutex sMutex;
		if (!gInstance)
		{
			boost::mutex::scoped_lock lock(sMutex);
			if (!gInstance)
			{
				gInstance = boost::shared_ptr<Log>(new Log());
			}
		}
		return gInstance;
	};
private:
	Log() {};

	std::vector<fun_call> m_Fun;
	boost::mutex m_Mutex;
};
typedef boost::shared_ptr<Log> LogPtr;


#define LOG_INFO(MSG) {std::stringstream tmpStream; tmpStream<<MSG; Log::getInstance()->notify("info", tmpStream.str());}


#endif
